#include "PropertyNode.h"


#include "Output/Console.h"
#include  "ScriptCompiler/Token/Token.h"
#include  "ScriptCompiler/AST/AccessLevelNode.h"
#include  "ScriptCompiler/AST/DecoratorNode.h"
#include  "ScriptCompiler/AST/UsingNode.h"
#include  "ScriptCompiler/AST/ClassNode.h"
#include  "ScriptCompiler/AST/DelegateNode.h"
#include  "ScriptCompiler/AST/EnumNode.h"
#include  "ScriptCompiler/AST/FunctionNode.h"
#include  "ScriptCompiler/AST/FieldNode.h"
#include  "ScriptCompiler/AST/PropertyNode.h"
#include  "ScriptCompiler/AST/ParameterNode.h"
#include  "ScriptCompiler/AST/SentenceBlockNode.h"
#include  "ScriptCompiler/AST/ExpressionNode.h"
#include  "ScriptCompiler/AST/NamespaceNode.h"
#include  "ScriptCompiler/AST/TypeNode.h"
#include  "ScriptCompiler/AST/GetAccessorNode.h"
#include  "ScriptCompiler/AST/SetAccessorNode.h"
#include  "ScriptCompiler/AST/PropertyIndexerNode.h"

void CPropertyNode::DebugPrint(int32_t InDepth)
{
    //print depth
    for(int32_t i = 0; i < InDepth; ++i)
    {
        WH::Print(U"\t");
    }

    if(AccessLevel.HasValue())
    {
        //print access level
        AccessLevel.GetValue()->DebugPrint(0);

        WH::Print(U" ");
    }

    //print decorator
    if(Decorator.HasValue())
    {
        Decorator.GetValue()->DebugPrint(0);

        WH::Print(U" ");
    }

    //print property type
    Type->DebugPrint(0);

    //print property name
    WH::Print(U" " + Name->ToString());

    //print property indexer
    if(Indexer.HasValue())
    {
        Indexer.GetValue()->DebugPrint(0);
    }

    if(DefaultValue.HasValue())
    {
        WH::Print(U"=> ");
        DefaultValue.GetValue()->DebugPrint(0);

        WH::Print(U";\n");
    }
    else
    {
        if(Getter.HasValue() or Setter.HasValue())
        {
            WH::Print(U"\n");
            //print { with depth
            for(int32_t i=0;i<InDepth;++i)
            {
                WH::Print(U"\t");
            }
            WH::Print(U"{\n");

            if(Getter.HasValue())
            {
                Getter.GetValue()->DebugPrint(InDepth+1);
            }

            if(Setter.HasValue())
            {
                Setter.GetValue()->DebugPrint(InDepth+1);
            }

            //print } with depth
            for(int32_t i=0;i<InDepth;++i)
            {
                WH::Print(U"\t");
            }
            WH::Print(U"}\n");
        }
        else
        {
            WH::Print(U";\n");
        }
    }

}

std::shared_ptr<CScriptToken> CPropertyNode::GetFirstToken()
{
    if(AccessLevel.HasValue())
    {
        return AccessLevel.GetValue()->GetFirstToken();
    }
    else if(DefaultValue.HasValue())
    {
        return DefaultValue.GetValue()->GetFirstToken();
    }
    else
    {
        return Type->GetFirstToken();
    }
}
